﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Runtime.InteropServices;
using System.Windows.Interop;

namespace Bainx.WPF.Extend
{
    public static class Element
    {
        /// <summary>
        /// 确定控件相关ContentPresenter.给出一个扩展方法
        /// </summary>
        /// <typeparam name="childElement"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static childElement FindVisualChild<childElement>
            (this DependencyObject obj) 
            where childElement : DependencyObject
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(obj, i);

                if (child != null && child is childElement)
                    return (childElement)child;
                else
                {
                    childElement childOfChild = FindVisualChild<childElement>(child);
                    if (childOfChild != null)
                        return childOfChild;
                }
            }
            return null;
        }
        /// <summary>
        /// 通过ContentControl控件的ContentTemplate属性的FindName方法获取元素
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static object FindTemplateChild
            (this ContentControl obj, string name)
        {
            ContentPresenter content = obj.FindVisualChild<ContentPresenter>();
            object child = obj.ContentTemplate.FindName(name, content);
            return child;
        }
        /// <summary>
        /// 通过ContentControl控件的ContentTemplate属性的FindName方法获取元素
        /// </summary>
        /// <typeparam name="childElement"></typeparam>
        /// <param name="obj"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static childElement FindTemplateChild<childElement>
            (this ContentControl obj, string name)  
            where childElement : DependencyObject
        {

            ContentPresenter content = obj.FindVisualChild<ContentPresenter>();
            object child = obj.ContentTemplate.FindName(name, content);
            if (child != null && child is childElement)
                return (childElement)child;
            return null;
        }
        /// <summary>
        /// 通过ContentControl控件的ContentTemplate属性的FindName方法获取元素
        /// (WinForm版)
        /// </summary>
        /// <typeparam name="childElement"></typeparam>
        /// <param name="obj"></param>
        /// <param name="name"></param>
        /// <param name="parent"></param>
        /// <returns></returns>
        public static childElement FindFormsTemplateChild<childElement>
            (this ContentControl obj, string name, FrameworkElement parent)
            where childElement : System.Windows.Forms.Control
        {
            object child = obj.ContentTemplate.FindName(name, parent);
            if (child != null && child is childElement)
                return (childElement)child;

            return null;
        }
        /// <summary>
        /// 获取元素父级元素
        /// </summary>
        /// <typeparam name="childElement"></typeparam>
        /// <param name="visual"></param>
        /// <returns></returns>
        public static childElement FindAncestor<childElement>
            (this Visual visual)
            where childElement : Visual
        {
            while (visual != null && !typeof(childElement).IsInstanceOfType(visual))
            {
                visual = (Visual)VisualTreeHelper.GetParent(visual);

            }
            if (visual != null && visual is childElement)
                return (childElement)visual;

            return null;
        }

        /// <summary>
        /// 从资源字典中取得x:key = Key的资源
        /// </summary>
        /// <typeparam name="Resource">资源类型</typeparam>
        /// <param name="ResourceDict">资源字典</param>
        /// <param name="Key">资源Key</param>
        /// <returns>资源</returns>
        public static Resource Find<Resource>(this ResourceDictionary ResourceDict, object Key)
        {
            Resource ret = (Resource)ResourceDict[Key];
            if (ret == null) throw new Exception(Key.ToString() + "不存在于此窗体模板中");
            return ret;
        }

      
    }
}
